
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <vector>
#include <sys/ioctl.h>
#include <netinet/if_ether.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/sockios.h>
#include <sys/time.h>
#include "net.h"
#include "comm.h"
using namespace std;

struct sockaddr_in6 client_addr;

void stop(int signo) {
  close(sock);
  close(send_sock);
  printf("\n已经关闭socket\n");
  exit(0);
}

int not_in_target_subnet(){
  char cip[40];
  char cmax[40]=IP_MAX;
  char cmin[40]=IP_MIN;
  char cpre[40]=IP_PRE;
  inet_ntop(AF_INET6,&client_addr.sin6_addr,cip,40);
  printf("接收ip为：%s\n",cip);
  int len=strlen(cip);
  int sublen;
  for(sublen=len-1;cip[sublen]!=':';sublen--);
  for(int i=0;i<=sublen;i++){
    if(cip[i]!=cpre[i]){
      printf("子网前缀不匹配\n");
      return 0;
    }
  }
    if(cip[sublen+1]==cmin[sublen+1]&&cip[sublen+1]==cmax[sublen+1]){
      printf("在目标子网内\n");
      return 0;
    }else{
      printf("此消息IP不在目标子网内\n");
      return 1;
    }
}

int main(int argc, char *argv[])
{
  signal(SIGINT,stop);
  int len;
	unsigned char* msg;
	unsigned char flag;
  send_sock=get_client_socket();
	sock = get_server_socket(PORT_WITH_DEFENSEC);
  if(send_sock!=-1&&sock!=-1){
    printf("sock is ready!  waiting for massages...\n");
  }
	while(1) {
    atack_type=0;
    recv_msg(sock, &len, 4,&client_addr,sizeof(client_addr));//先接收一个长度信息
		msg = (unsigned char*)malloc(len);
		recv_msg(sock, msg, len,&client_addr,sizeof(client_addr));
    // if(len==3){
    //   memcpy(&flag, msg, 1);//解析数据类型
    // }else{
      memcpy(&flag, msg+4, 1);//解析数据类型
//    }

    if(flag== 0x12){//0x12表示攻击类型信息
      printf("receive a atack_type massage:len=%d\n",len);
      memcpy(&atack_type, msg+5,1);
      if(atack_type==0){
        printf("atack_type is 0\n");
        continue;
      }
      //发送类型信息到展示台
      send_to_display(send_sock,&len, sizeof(int),DISPLAY_IP,DISPLAY_PORT);
      send_to_display(send_sock,msg,len,DISPLAY_IP,DISPLAY_PORT);
      printf("send a atack_type to display\n");
      if(not_in_target_subnet()){//不在目标ip子网内
        //发送类型信息到防御执行器，启动防御执行器
        send_msg(send_sock,&atack_type,1,client_addr);
        printf("send a atack_type to defence_e\n");
      }

    }else if(flag == 0x11) {//告警解除信息
      printf("receive a alert cancel type massage:len=%d\n",len);
      //发送类型信息到展示台
      send_to_display(send_sock,&len, sizeof(int),DISPLAY_IP,DISPLAY_PORT);
      send_to_display(send_sock,msg,len,DISPLAY_IP,DISPLAY_PORT);
      printf("send a alert_cancel to display\n");
      if(not_in_target_subnet()){
        //发送解除告警信息到防御执行器
        atack_type=0;//攻击类型设置为0，表示解除告警
        send_msg(send_sock, &atack_type, 1, client_addr);
        printf("send a alert cancel to defene_e\n");
      }

		} else{
      char cips[40];
      inet_ntop(AF_INET6,&client_addr.sin6_addr,cips,40);
      printf("接收ip为：%s---error msg--len=%d type=%x massage:%s\n",cips,len,flag,msg);
    }
	}
	return 0;
}
